﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace commonlib
{
    public class DataServerServices : MarshalByRefObject, IDataServerServices
    {

        private DataStore storage;
        private Transaction transaction;

        public STATES state
        {
            get;
            set;
        }

        public DataServerServices(DataServer node,STATES state)
        {
            this.storage = new DataStore(node);
            this.state = state;
        }

        #region IDataServerServices Members

        public List<SystemComponent> updateSystemComponentsStates(List<SystemComponent> components)
        {
            Console.WriteLine("< central directory state > {0} componentes registados.", components.Count);
            return components;
        }

        #endregion

        #region IDataServerServices Members

        public bool begin(long txId)
        {
            Console.WriteLine("<Data Server> begin transaction...");
            if (this.transaction == null)
            {
                Console.WriteLine("<Data Server> transaction initiated");
                this.transaction = new Transaction();
                this.transaction.txId = txId;
                this.transaction.state = TRANSACTION_STATES.INITIATED;
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool put(string key, string value, long txId)
        {
            try
            {
                this.storage.put(key, value, txId);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /**
        * Este método retorna um Tuplo para uma key e um txId dados
        **/
        public Tuple get(string key, long txId)
        {
            try
            {
                return this.storage.get(key, txId);
            }
            catch (Exception)
            {
                throw new PaditableException("Não existe um registo com a chave: " + key);
            }

        }

        public bool commit(long txId)
        {
            if (this.transaction.state == TRANSACTION_STATES.TENTATIVELY_COMMITED)
            {
                this.transaction.state = TRANSACTION_STATES.COMMITED;
                return true;
            }
            else
            {
                return false;
            }

        }

        public bool abort(long txId)
        {
            throw new NotImplementedException();
        }

        public List<Tuple> getAll(string key)
        {
            throw new NotImplementedException();
        }


        public void setState(string name,STATES state)
        {
            this.state = state;
            Console.WriteLine("{0} está {1}",name,state==STATES.OFFLINE?"Offline":"Online");
        }

        #endregion


    }
}
